/* 
 * GWT-Ext Widget Library 
 * Copyright 2007 - 2008, GWT-Ext LLC., and individual contributors as indicated 
 * by the @authors tag. See the copyright.txt in the distribution for a 
 * full listing of individual contributors. 
 * 
 * This is free software; you can redistribute it and/or modify it 
 * under the terms of the GNU Lesser General Public License as 
 * published by the Free Software Foundation; either version 3 of 
 * the License, or (at your option) any later version. 
 * 
 * This software is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
 * Lesser General Public License for more details. 
 * 
 * You should have received a copy of the GNU Lesser General Public 
 * License along with this software; if not, write to the Free 
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org. 
 */

package edu.rpi.tw.pml.browsing.client;

import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.gwtext.client.data.*;
import com.gwtext.client.widgets.MessageBox;
import com.gwtext.client.widgets.Panel;
import com.gwtext.client.widgets.grid.ColumnConfig;
import com.gwtext.client.widgets.grid.ColumnModel;
import com.gwtext.client.widgets.grid.GridPanel;
import com.gwtext.client.widgets.layout.ColumnLayout;
import com.gwtext.client.widgets.layout.ColumnLayoutData;
import edu.rpi.tw.pml.browsing.client.InstanceTableDataProvider.TableDataAcceptor;
import edu.rpi.tw.pml.browsing.client.util.JSONParser;

public class InstanceTableWidget {

	private final Panel panel = new Panel();
	private final InstanceTableDataProvider provider;
	private final TableDataAcceptor acceptor = new TableDataAcceptorImpl();
	private final FacetSearchServiceAsync proxy;
	private LinkedHashMap<String, Object[][]> map = new LinkedHashMap<String, Object[][]>();

	// private Store store;
	// private RecordDef recordDef;

	public InstanceTableWidget(InstanceTableDataProvider p) {
		provider = p;
		panel.setBorder(false);
		panel.setPaddings(5, 2, 2, 5);
		panel.setLayout(new ColumnLayout());
		panel.setAutoScroll(true);

		// Load data via RPC.
		proxy = GWT.create(FacetSearchService.class);
		proxy.getAllInstances(new AsyncCallback<String>() {
			public void onFailure(Throwable caught) {
				System.out.println("Error while loading all instances.");
			}

			public void onSuccess(String result) {
				map = JSONParser.string2HashMap(result);
				Set entries = map.entrySet();

				for (Iterator iterator = entries.iterator(); iterator.hasNext();) {
					Map.Entry<String, Object[][]> entry = (Map.Entry<String, Object[][]>) iterator
							.next();
					buildGrid(entry);
				}
			}
		});
	}

	private void buildGrid(Map.Entry<String, Object[][]> entr) {
		String gridTitle = entr.getKey();
		Object[][] gridData = entr.getValue();

		MemoryProxy proxy = new MemoryProxy(gridData);
		RecordDef recordDef = new RecordDef(new FieldDef[] {
				new StringFieldDef("property"), new StringFieldDef("value") });

		ArrayReader reader = new ArrayReader(recordDef);

		Store store = new Store(proxy, reader);
		store.load();

		ColumnConfig[] columns = new ColumnConfig[] {
				new ColumnConfig("Property", "property", 500, true, null),
				new ColumnConfig("Value", "value", 300, true, null, "column") };

		ColumnModel columnModel = new ColumnModel(columns);

		GridPanel grid = new GridPanel();
		grid.setStore(store);
		grid.setColumnModel(columnModel);
		grid.setFrame(true);
		grid.setStripeRows(true);
		grid.setAutoExpandColumn("column");
		grid.setHeight(200);
		grid.setWidth(978);
		grid.setTitle(gridTitle);
		grid.setCollapsible(true);
		grid.setAnimCollapse(true);
		grid.setIconCls("grid-icon");

		panel.add(grid, new ColumnLayoutData(1.0));
		panel.add(grid);
		// force container to redraw after being rendered.
		panel.doLayout();
	}

	public Panel getPanel() {
		return this.panel;
	}

	public void refresh() {
		// MessageBox.alert("Test", "InstanceTableWidget.refresh()");
		provider.updateTable(acceptor);

	}

	// for test
	// private Object[][] getInstanceData() {
	// return new Object[][] {
	// new Object[] { "http://www.example.org/dataset#hasURL",
	// "http://www.example.org/shangz" },
	// new Object[] { "http://www.example.org/dataset#hasName",
	// "Zhenning Shangguan" },
	// new Object[] { "http://www.example.org/dataset#type",
	// "http://foaf.org/spec/Person" },
	// new Object[] { "http://www.example.org/dataset#Location",
	// "Rensselaer Polytechnic Institute" },
	// new Object[] { "http://www.example.org/dataset#mbox",
	// "shangz@cs.rpi.edu" } };
	// }

	/*
	 * Inner class for updating InstanceTableWidget.
	 */
	private class TableDataAcceptorImpl implements TableDataAcceptor {
		public void accept(String result) {
			panel.removeAll(true);
			panel.doLayout();
			map = JSONParser.string2HashMap(result);
			Set entries = map.entrySet();

			for (Iterator iterator = entries.iterator(); iterator.hasNext();) {
				Map.Entry<String, Object[][]> entry = (Map.Entry<String, Object[][]>) iterator
						.next();
				buildGrid(entry);
			}
		}

		public void failed(Throwable caught) {
			System.out
					.println("Error while loading instances according to user selected facet values.");
		}
	}
}